
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.DataInputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.SocketConnection;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.Ticker;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.midlet.*;
import org.kxml2.io.KXmlParser;
import org.kxml2.kdom.Document;
import org.kxml2.kdom.Element;
import org.xmlpull.v1.XmlPullParserException;

/**
 * @author rachid 
 */
public class PacketReader extends Thread {

    private Display display;
    private Form displayForm;
	private StringItem dataInfo;
    private Command stopCommand;
	private Command retCommand;
	private Ticker ticker;
	private String group;
	private SocketConnection sc ;
    private DataInputStream input;			
	private KXmlParser parser ;
    private Document doc;
	private Xapp parent;
	private boolean started;
	private String serverName;
    private String serverPort;
	
	private DataRecord db;
	
	Element root, sub, name, value;
    String packetType, groupId, nodeId, temp;
  	String res = "";
	
	boolean validPacket=true;
   
    public PacketReader( Xapp app, DataRecord db, String server, String port) {
		
	    this.db=db;
		parent=app;
		serverName= server;
		serverPort= port;
		group=db.getName();
		
		display= Display.getDisplay(parent);
        stopCommand = new Command("Stop",Command.STOP, 0);
		retCommand = new Command("Return",Command.OK, 0);
        displayForm = new Form("");
        dataInfo = new StringItem("stats\n", null);
		ticker = new Ticker("collecting data");
        displayForm.append(dataInfo);
        displayForm.addCommand(stopCommand);
		displayForm.addCommand(retCommand);
		displayForm.setTicker(ticker);
        displayForm.setCommandListener(parent);
		//display.setCurrent(displayForm);
		
    }
	
	public Displayable getDisplay(){
	
		return displayForm;
	
	}

		/*
    public void commandAction(Command cmd, Displayable d) {
	
		String label = cmd.getLabel();
        if (label.equals("Stop")){
		
			started=false;
			display.setCurrent(parent.getAdressForm());
			close();
		
		} 
    }
	
	 */
    public static int swapBytes( int value ) {
        int b1 = ( value ) & 0xff;
        int b2 = ( value >> 8 ) & 0xff;
        int b3 = ( value >> 16 ) & 0xff;
        int b4 = ( value >> 24 ) & 0xff;

        return b1 << 24 | b2 << 16 | b3 << 8 | b4;
    }
	
	
	void parse(byte[] xml) {
	
    	res = "";
        validPacket=true;
		
        try {
            parser.setInput(new InputStreamReader(new ByteArrayInputStream(xml)));
            doc.parse(parser);
            
            root = doc.getRootElement();
           
			packetType=root.getElement(0).getElement(1).getText(0);//get packet type
			if(packetType.compareTo("11")!=0) validPacket=false;
			
			else {
				nodeId=root.getElement(1).getElement(1).getText(0);//get node identifier
                res+= "nodeId "+nodeId +"\n";
				
				for ( int i = 2; i < root.getChildCount(); ++i ) {
					sub = root.getElement(i);
					name=sub.getElement(0);
					
					/*looking for group id */
			    	if(name.getText(0).compareTo("group")==0){ 
						value=sub.getElement(1);
						groupId=value.getText(0); //get group id
						if(groupId.compareTo(group)!=0) break;
						res+="groupId "+ groupId+"\n";
					}
					else{ /*looking for temp value */
					
						if(name.getText(0).compareTo("temp")==0){ 
							value=sub.getElement(1);
							temp=value.getText(0).substring(0,2); // getting temp value
							res+="temp "+ temp+"\n";
							db.put(nodeId, temp);
							
							break;// seulement la temperature qui nous interesse
						}
					}					
				}     
				
			dataInfo.setText(db.print());
			
			}
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (XmlPullParserException ex) {
		
			System.out.println("packet invalide");
			validPacket=false;
			skip();
		 
        }
	     
	}
	
	/* Sert a se debarasser de ce qui reste du packet precedent si invalide*/
	void skip(){
		try{
		
			byte[] buf=new byte[input.available()];
			input.read(buf);
			buf=null;
			
		}catch(Exception e){
		
			//Afficher alert
			
		}
	
	}
	
	public void close(){
		try{
			started=false;
			db.emptyRecordStore();
			sc.close();
			input.close(); 
			 
			
		}catch(Exception e){
		
			//Afficher alert
			
		}
	
	}
	
    public void run() {
	   
			started=true;
			
			parser = new KXmlParser();
			doc = new Document();
			byte[] packet = null;
			int size;
			
		try {
		
			sc = (SocketConnection) Connector.open("socket://"+serverName+":"+serverPort);
			input = sc.openDataInputStream();
			
			while(started){		
					
			    size = input.readInt(); 
				size = swapBytes(size); //System.out.println(" taille :"+size);
				if (size>4095)  skip();
				packet  = new byte[size];
				input.read(packet);
			 
			    ///pas necessaire juste pour affichage a la console du packet
				String text = new String(packet);
				//System.out.println(size +" "+text.length()+" "+text);
				
				parse(packet);
				
				Thread.sleep(1000);
				
			}

        }
        catch (Exception e) {
			
           Alert alert = new Alert("Error ",
                        "An error occurred while communicating with the server.", 
						null, AlertType.ERROR);
            alert.setTimeout(Alert.FOREVER);
            display.setCurrent(alert, parent.getAdressForm());

			close();          
        }			
    }	
}
